package name.katlog.refactor._08reorganizedata;

import lombok.Data;
import org.junit.Test;

/**
 * Created by fw on 2018/4/24
 * 以State/strategy 取代型别码
 */
@SuppressWarnings("ALL")
public class ReplaceTypeCodewithStateOrStrategy {

    @Test
    public void fun(){
        //System.out.println(new Original().fun());
        //System.out.println("this employee'sal is "+new Refactor1().new Employee(1).payAmount());
        System.out.println("this employee'sal is "+new Refactor2().new Employee(1).payAmount());
    }

    class Refactor3 {

        abstract class EmployeeType {

            protected final int _monthlySalary/*月工资*/ = 2000;
            protected final int _commission/*提成*/ = 100;
            protected final int _bonus/*奖金*/ = 500;

            abstract int getTypeCode();

            public abstract int payAmount();
        }

        class Engineer extends EmployeeType {

            @Override
            int getTypeCode() {
                return Employee.ENGINEER;
            }

            @Override
            public int payAmount() {
                return _monthlySalary;
            }
        }

        class SALESMAN extends EmployeeType {

            @Override
            int getTypeCode() {
                return Employee.SALESMAN;
            }

            @Override
            public int payAmount() {
                return _monthlySalary+_commission;
            }
        }

        class MANAGER extends EmployeeType {

            @Override
            int getTypeCode() {
                return Employee.MANAGER;
            }

            @Override
            public int payAmount() {
                return _monthlySalary+_bonus;
            }
        }

        class Employee {
            private EmployeeType type;
            static final int ENGINEER = 0;
            static final int SALESMAN = 1;
            static final int MANAGER = 2;

            public Employee(int type) {
                setType(type);
            }

            int getTypeCode() {
                return type.getTypeCode();
            }

            public void setType(int arg) {
                switch (arg) {
                    case ENGINEER:
                        type = new Engineer();
                    case SALESMAN:
                        type = new SALESMAN();
                    case MANAGER:
                        type = new MANAGER();
                    default:
                        throw new RuntimeException("Incorrect Employee");
                }
            }

            //self Encapsulate/*封装*/ Field
            // replace conditional with Polymorphism/*跑垒毛飞泽姆*/
            int payAmount() {
                return type.payAmount();
            }

        }
    }

    /**
     * 引入抽象父类
     */
    class Refactor2 {

        abstract class EmployeeType {
            abstract int getTypeCode();
        }

        class Engineer extends EmployeeType {

            @Override
            int getTypeCode() {
                return Employee.ENGINEER;
            }
        }

        class SALESMAN extends EmployeeType {

            @Override
            int getTypeCode() {
                return Employee.SALESMAN;
            }
        }

        class MANAGER extends EmployeeType {

            @Override
            int getTypeCode() {
                return Employee.MANAGER;
            }
        }

        @Data
        class Employee {
            private int type;
            private final int _monthlySalary/*月工资*/ = 2000;
            private final int _commission/*提成*/ = 100;
            private final int _bonus/*奖金*/ = 500;
            static final int ENGINEER = 0;
            static final int SALESMAN = 1;
            static final int MANAGER = 2;

            public Employee(int type) {
                setType(type);
            }

            int payAmount() {
                switch (getType()) {
                    case ENGINEER:
                        return _monthlySalary;
                    case SALESMAN:
                        return _monthlySalary + _commission;
                    case MANAGER:
                        return _monthlySalary + _bonus;
                    default:
                        throw new RuntimeException("Incorrect Employee");
                }
            }

        }
    }

    /**
     * 添加getter和setter
     * 使用方法代替字段直接使用
     */
    class Refactor1 {
        @Data
        class Employee {
            private int type;
            private final int _monthlySalary/*月工资*/ = 2000;
            private final int _commission/*提成*/ = 100;
            private final int _bonus/*奖金*/ = 500;
            static final int ENGINEER = 0;
            static final int SALESMAN = 1;
            static final int MANAGER = 2;

            public Employee(int type) {
                setType(type);
            }

            int payAmount() {
                switch (getType()) {
                    case ENGINEER:
                        return _monthlySalary;
                    case SALESMAN:
                        return _monthlySalary + _commission;
                    case MANAGER:
                        return _monthlySalary + _bonus;
                    default:
                        throw new RuntimeException("Incorrect Employee");
                }
            }

        }
    }

    /**
     * 雇员类有计算工资的方法
     */
    class Original {
        @Data
        class Employee {
            private int type;
            private final int _monthlySalary/*月工资*/ = 2000;
            private final int _commission/*提成*/ = 100;
            private final int _bonus/*奖金*/ = 500;
            static final int ENGINEER = 0;
            static final int SALESMAN = 1;
            static final int MANAGER = 2;

            int payAmount() {
                switch (type) {
                    case ENGINEER:
                        return _monthlySalary;
                    case SALESMAN:
                        return _monthlySalary + _commission;
                    case MANAGER:
                        return _monthlySalary + _bonus;
                    default:
                        throw new RuntimeException("Incorrect Employee");
                }
            }

        }

        public int fun(){
            Employee employee = new Employee();
            employee.setType(1);
            return employee.payAmount();
        }
    }


}
